import CryptoJS from 'crypto-js';
import { default as Crypto } from 'crypto-js'
import {JSEncrypt} from "jsencrypt";
import { v4 as uuidv4 } from "uuid";
import forge from "node-forge";
import { DateTime } from 'luxon';

//当前程序公钥
const pubKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxFa1G7jBAql18Gu3R+AV
M7u8U+SMzFDS0tcJyZdKaZ45W2HQ8JZXJOgqTCmm0o0pqXQytNfubelk9yNd9+Oi
PMERzef1mkZ4CvVupofTZq+WBReXLW0msPPDL+h0dYv45dp9PCBrETUPLbiidnT+
sMOLUFuj8TJIGh/tjJFBmwu7GbukoNU4kcUY4eKtJmsXao7K6t7Rm52ivR9EIZKn
Iic5ajiY5vqg1SaLJuRq7gFfcovotnbUFT3eKdEqU6gDE/8gPzPTOe1xerlR4JB6
yCX7JjpJhTggexT8pun6HVqXkeVjheP8p7jwvBkkWTC/sx6S7TKvPhLbLb3E//mX
4QIDAQAB
-----END PUBLIC KEY-----`

function rsaOaepEncrypt(plaintext: string) {
  // 从PEM导入公钥
  const publicKey = forge.pki.publicKeyFromPem(pubKey);
  
  // 根据选择的哈希算法创建对应的md对象
  const md = forge.md.sha1.create();
  
  // 执行加密
  const encrypted = publicKey.encrypt(
    forge.util.encodeUtf8(plaintext),
    'RSA-OAEP',
    {
      md: md,
      mgf1: {
        md: md
      }
    }
  );
  
  // 返回Base64编码结果
  return forge.util.encode64(encrypted);
}

export const encryptFun = async (word: string) =>{
  const encrypted = rsaOaepEncrypt(word);
  const _encrypted = CryptoJS.enc.Base64.parse(encrypted);
  return CryptoJS.enc.Hex.stringify(_encrypted);
}

function otherRsaOaepEncrypt(_publicKey: string, plaintext: string) {
  const _pubKey = `-----BEGIN PUBLIC KEY-----${_publicKey}-----END PUBLIC KEY-----`
  // 从PEM导入公钥
  const publicKey = forge.pki.publicKeyFromPem(_pubKey);
  
  // 根据选择的哈希算法创建对应的md对象
  const md = forge.md.sha1.create();
  
  // 执行加密
  const encrypted = publicKey.encrypt(
    forge.util.encodeUtf8(plaintext),
    'RSA-OAEP',
    {
      md: md,
      mgf1: {
        md: md
      }
    }
  );
  
  // 返回Base64编码结果
  return forge.util.encode64(encrypted);
}

export const otherEncryptFun = async (publicKey: string, word: string) =>{
  const encrypted = otherRsaOaepEncrypt(publicKey, word);
  const _encrypted = CryptoJS.enc.Base64.parse(encrypted);
  return CryptoJS.enc.Hex.stringify(_encrypted);
}


const mixSaltCharByChar = (s:any, salt:any) => {
  const maxLength = Math.max(s.length, salt.length);
  let result = "";
  for (let i = 0; i < maxLength; i ++) {
      if (s.length > i) {
          result += s.charAt(i);
      }
      if (salt.length > i) {
          result += salt.charAt(i);
      }
  }
  return result;
}

declare global {
  interface String {
    replaceAll(searchValue: string | RegExp, replaceValue: string): string;
  }
}

String.prototype.replaceAll = function(searchValue, replaceValue) {
  return this.replace(new RegExp(searchValue, 'g'), replaceValue);
};
export const raTokenFun = () => {
  const uuid =  uuidv4().replaceAll("-", "");
  const tsStr = new Date().getTime().toString();
  const mixedStr = mixSaltCharByChar(tsStr, uuid);
  const sha = Crypto.SHA512(mixedStr).toString();
  return uuid + sha.slice(sha.length - 10) + tsStr;
}

export const ConvertToDateFun = (dateStr:string, format:string) => {
  if(dateStr === null) {
    return '--'
  } else {
    const date = DateTime.fromISO(dateStr)
    return date.toFormat(format)
  }
}
